Kanzi Studio 插件扩展 Kanzi Studio 的功能并在 Kanzi Studio 中运行。 使用 Kanzi Studio 插件:
您可以在包含Kanzi Studio 插件用户界面的 Kanzi Studio 窗口中呈现插件,也可以将其作为用户可以从上下文菜单中执行的命令,在没有用户界面的情况下运行插件。本主题介绍如何创建 Kanzi Studio 窗口插件。要了解如何创建 Kanzi Studio 命令插件,请参阅 创建 Kanzi Studio 命令插件。
创建 Kanzi Studio 窗口的默认 UI 框架是 WPF。但是,您可以使用在 HTML 上运行且使用 WPF 中的 Web 浏览器控件的框架,或通过将使用 WPF 的 HwndHost 控件(托管 win32 窗口作为元素)的内容嵌入 WPF 内容中来使用其他框架。
Kanzi Studio 插件接口作为 .NET 框架程序集提供。您可以在 <KanziInstallation>/Studio/Bin/PluginInterface.dll 中找到它。插件接口可用于访问Kanzi Studio 中的数据和命令。When you want to use a Kanzi Studio plugin with different versions of Kanzi Studio, build the plugin with the PluginInterface.dll from each version of Kanzi Studio where you want to use that plugin.
要开发 Kanzi Studio 窗口插件,请执行以下操作:
要查找有关 Kanzi Studio 插件接口的详细信息,请参阅:
Kanzi Studio 窗口插件是在 Kanzi Studio 窗口中使用的插件,有用户界面。例如,使用窗口插件来创建编辑器或可视化工程中的内容。
您可在这里创建 Kanzi Studio 窗口插件的基项,然后向其中添加功能来扩展 Kanzi Studio 的功能。
要创建 Kanzi Studio 窗口插件:
System.ComponentModel.Composition
System.XAML
在 Solution Explorer 中,右键点击工程名称,选择属性 (Properties),并:
UserControl1.xaml.cs
文件,并为 Kanzi Studio 插件接口添加 using 指令:using Rightware.Kanzi.Studio.PluginInterface;
UserControl1
类设置为实现 PluginWindow
接口:public partial class UserControl1 : UserControl为
public partial class UserControl1 : UserControl, PluginWindow
PluginWindow
界面。PluginWindow
, 上,点击 ,然后选择实现界面 (Implement Interface)。UserControl1
类添加 KanziStudio
接口。 KanziStudio
接口是使用 Kanzi Studio 插件 API 进行操作的入口点。private KanziStudio studio;
throw new NotImplementedException();
确保插件处理所有内部异常,不让它们传递到 Kanzi Studio 界面。
例如,设置UserControl1
类中的函数:UserControl1
添加 studio
参数。这让您可以实例化 UserControl1
并提供 studio
作为 Class1.cs
文件中的参数。public UserControl1(KanziStudio studio) { this.studio = studio; InitializeComponent(); }
Icon
函数设置在插件窗口的左上角显示的插件窗口图标:public string Icon { get { return ""; } }
SerializeState
函数保存插件窗口的状态。当您关闭插件窗口时,Kanzi Studio 会调用函数。如果您再次打开插件窗口,Kanzi Studio 会在创建插件窗口时会传递相同的状态作为参数。null
时,Kanzi Studio 不会记忆窗口的状态。public PluginWindowState SerializeState() { return null; }
Title
函数以设置您要显示为插件窗口标题的文本。例如,将其设为:public string Title { get { return "Plugin title"; } }
Dispose
函数进行清理。例如,您可以在这里释放您在插件中使用的所有资源,并且如果您的插件订阅任何事件,则在此处取消订阅这些事件。当用户关闭插件窗口时,Kanzi Studio 调用函数。Class1.cs
文件,并为 System.ComponentModel.Composition
和 Kanzi Studio 插件接口添加 using 指令:using System.ComponentModel.Composition; using Rightware.Kanzi.Studio.PluginInterface;
Class1
类以实现 PluginWindowFactory
接口,这是您在 Class1
类中实现的接口。Kanzi 使用该类来创建插件。Kanzi Studio 首先获取 factory 并定义插件名称、窗口大小、插件是否有窗口,以及用户可以从 Kanzi Studio 中的哪里启动插件。public class Class1为
public class Class1 : PluginWindowFactory
PluginWindowFactory
界面。PluginWindowFactory
, 上,点击 ,然后选择实现界面 (Implement Interface)。PluginWindowFactory
接口实现为 Kanzi Studio 的插件内容。如此一来,Kanzi Studio 就知道 .dll 是一个插件。[Export(typeof(PluginContent))]
throw new NotImplementedException();
确保插件处理所有内部异常,不让它们传递到 Kanzi Studio 界面。
例如,设置Class1
类中的函数:CreateWindow
函数可实例化 UserControl1
并提供 studio
作为参数。您向 UserControl1.xaml.cs
文件中的 UserControl1
添加了 studio
参数。public PluginWindow CreateWindow(PluginWindowState state) { return new UserControl1(studio); }
DefaultHeight
和 DefaultWidth
函数用于插件窗口的高度和宽度。例如,要设置 400 × 400 像素插件窗口,请使用:get { return 400; }
CanExecute
函数设置用户能否启动插件以及在哪里启动插件:false
时,Kanzi Studio 在主菜单和上下文菜单中显示插件,但用户无法启动插件。true
时,用户可以启动插件。Kanzi Studio 为插件提供 KanziStudio
对象。KanziStudio
对象是数据访问的根对象,提供当前工程、可用命令、全局撤销和重做,以及与工程打开和关闭有关的事件。
例如,仅当 Kanzi Studio 工程打开时才使用此设置以启用命令
private KanziStudio studio; public bool CanExecute(PluginCommandParameter parameter) { return this.studio != null && this.studio.ActiveProject != null; }
CommandPlacement
函数设置插件的菜单名称以及在哪里显示命令以启动插件:ContextMenuPlacement.NONE
。ContextMenuPlacement.PROJECT_ITEM
。public CommandPlacement CommandPlacement { get { return new CommandPlacement("myPluginMenu", ContextMenuPlacement.NONE, false, null); } }
Description
函数来设置 Kanzi Studio 插件内容的简要描述。用户将鼠标指针悬停在菜单中的插件名称上时,Kanzi Studio 会将本描述显示为工具提示。public string Description { get { return "A tooltip with short description of what the plugin does."; } }
DisplayName
函数在 Kanzi Studio 菜单中显示插件名称,您可以在其中启动插件。public string DisplayName { get { return "Plugin display name"; } }
Name
函数设置插件的内部名称。Kanzi 使用插件的内部名称,以便您在不对插件进行其他更改的情况下更改插件的显示名称。public string Name { get { return "Internal plugin name"; } }
Initialize
函数将 studio
置于成员变量中。public void Initialize(KanziStudio studio) { this.studio = studio; }
您在此处创建了 Kanzi Studio 窗口插件的基本结构,仅打开一个空窗口。要让插件执行更多操作,请向窗口添加功能。请参阅 向 Kanzi Studio 窗口插件添加功能 和 将 Kanzi Studio 窗口插件中的工程更改进行分组。
要进一步开发您的 Kanzi Studio 插件,请参阅 Kanzi Studio 插件接口概览和 Kanzi Studio 插件接口 API 参考。
要构建和运行 Kanzi Studio 插件:
将 Kanzi Studio 插件 .dll 复制到 %ProgramData%\Rightware\<KanziVersion>\plugins 目录。
如果 plugins 目录在 %ProgramData%\Rightware\<KanziVersion> 中不存在,请创建。
创建 Kanzi Studio 窗口插件的基项后,向您的插件添加功能,以使其发挥些作用。您可在这里创建显示当前选定节点或资源的 kzb 文件 URL 的插件。
要向 Kanzi Studio 窗口插件添加功能:
PluginWindow
接口的类文件。UserControl1.xaml.cs
类文件。PluginWindow
接口的类中,添加当您与插件窗口中的插件交互时插件执行的代码。public partial class UserControl1 : UserControl, PluginWindow { private KanziStudio studio; public UserControl1(KanziStudio studio) { this.studio = studio; InitializeComponent(); //订阅 SelectionChanged 事件,以了何时节点选择或资源发生了更改。 studio.SelectionChanged += Studio_SelectionChanged; //设置插件窗口的内容。 Populate(); } //当前选定的工程项更改时,设置插件窗口的内容。 private void Studio_SelectionChanged(object sender, EventArgs e) { Populate(); } //设置显示当前选定工程项的名称和 kzb 文件 URL 的控件中的文本。 public void Populate() { var currentSelection = studio.SelectedItems.FirstOrDefault(); this.selectionTextBlock.Text = (currentSelection != null) ? currentSelection.Name : "< no project item selected >"; this.kzbUrlTextBox.Text = (currentSelection != null) ? currentSelection.KzbUrl : " "; } ... //设置插件窗口的标题。 public string Title { get { return "Project item kzb file URL"; } } ... //处置窗口使用的资源。 public void Dispose() { if (studio != null) { this.studio.SelectionChanged -= Studio_SelectionChanged; } } ... }
UserControl1.xaml
文件并替换<Grid> </Grid>为
<StackPanel Margin="5"> <Label Content="Project Item" /> <TextBlock x:Name="selectionTextBlock" Margin="10,5" /> <Label Content="kzb file URL" /> <TextBox x:Name="kzbUrlTextBox" Margin="10,5" IsReadOnly="True" /> </StackPanel>
将 Kanzi Studio 窗口插件中的工程更改分组,使更改作为一个命令向 Kanzi Studio 用户显示。通过这种方式,您可以设置撤销和重做命令来影响整组更改而不是单个更改。
例如,当 Kanzi Studio 窗口插件在用户点击按钮时对工程应用一系列修改时,如果您希望 Kanzi Studio 在用户选择 > 撤销 (Undo) 时立即撤销所有这些修改,将工程更改分组。
使用批量修改将 Kanzi Studio 窗口插件应用于工程的一系列更改分组。您使用批量修改时,听从所修改事件的对象可以跳过批量修改期间发生的事件,并在批量修改完成时应用所有更改。
要将 Kanzi Studio 窗口插件中的工程更改分组:
PluginWindow
接口的类文件。UserControl1.xaml.cs
类文件。PluginWindow
接口的类中,添加当您与插件窗口中的插件交互时插件执行的代码。//如果具有给定名称的参考线已存在,则函数返回 true。 private bool GuideExists(string guideName) { bool exists = false; var guides = studio.ActiveProject.Guides; foreach (var guide in guides) { var name = guide.Get(Properties.Name); if (name == guideName) { exists = true; } } return exists; } //此函数创建参考线。 private void CreateGuides(int step, int count, bool isVertical) { var guides = studio.ActiveProject.Guides; for (int i = 1; i <= count; i++) { String guideName; Vector guidePosition; var coordinate = i * step; //设置参考线位置和名称。 if (isVertical) { guidePosition = new Vector(coordinate, 0); guideName = "Guide_V" + Convert.ToString(coordinate); } else { guidePosition = new Vector(0, coordinate); guideName = "Guide_H" + Convert.ToString(coordinate); } //检查是否存在名称相同的参考线 bool exists = GuideExists(guideName); if (!exists) { //新建参考线。 var guide = studio.ActiveProject.CreateProjectItem<Guide>(guideName, null); //设置参考线位置。 guide.Set(Properties.GuidePosition, guidePosition); //对于垂直参考线,设置旋转 (Rotation) 属性。 if (isVertical) { guide.Set(Properties.GuideRotation, (float)Math.PI/2); } } } }
BeginBatchModification
和 CommitBatchModification
函数之间。private void Button_Click(object sender, RoutedEventArgs e) { //水平参考线之间的距离 var horizontalStep = Convert.ToUInt16(hStepInput.Text); //水平参考线的数量 int horizontalCount = Convert.ToUInt16(hCountInput.Text); //垂直参考线之间的距离 var verticalStep = Convert.ToUInt16(vStepInput.Text); //垂直参考线的数量 int verticalCount = Convert.ToUInt16(vCountInput.Text); //开始名为 Create Guides 的批量修改 studio.ActiveProject.BeginBatchModification("Create Guides"); //为您要在批处理中执行的代码调用函数。 CreateGuides(horizontalStep, horizontalCount, false); CreateGuides(verticalStep, verticalCount, true); //完成批量修改 studio.ActiveProject.CommitBatchModification(); }
UserControl1.xaml
文件并替换<Grid> </Grid>为
<StackPanel HorizontalAlignment="Center"> <Grid Margin="0,10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="150" /> <ColumnDefinition Width="45" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Label Margin="0,0,0,2" Grid.Column="0" Grid.Row="0" FontWeight="Bold">Horizontal Guides</Label> <Label Margin="5,2,0,2" Grid.Column="0" Grid.Row="1">Number of guides</Label> <TextBox Margin="0,2" Grid.Column="1" Grid.Row="1" Name="hCountInput" Text="10" /> <Label Margin="5,2,0,2" Grid.Column="0" Grid.Row="2">Distance between guides</Label> <TextBox Margin="0,2" Grid.Column="1" Grid.Row="2" Name="hStepInput" Text="100" /> <Label Margin="0,10,0,2" Grid.Column="0" Grid.Row="3" FontWeight="Bold">Vertical Guides</Label> <Label Margin="5,2,0,2" Grid.Column="0" Grid.Row="4">Number of guides</Label> <TextBox Margin="0,2" Grid.Column="1" Grid.Row="4" Name="vCountInput" Text="10" /> <Label Margin="5,2,2,2" Grid.Column="0" Grid.Row="5">Distance between guides</Label> <TextBox Margin="0,2" Grid.Column="1" Grid.Row="5" Name="vStepInput" Text="100" /> </Grid> <Button Padding="5,3" Content="Create Guides" Click="Button_Click" /> </StackPanel>
要查看 Kanzi Studio 工程中的参考线,在预览 (Preview) 中点击 进入分析 (Analyze) 模式,右键点击 并选择 标尺和参考线 (Rulers and guides)。